#include "stdafx.h"
#include "BasicSkinWidgetDelegate.h"
#include "IBasicResourceMgr.h"
#include "BasicSkinView.h"
#include "BasicSkinWidget.h"

namespace BasicSkinView
{

	CBasicSkinWidgetDelegate::CBasicSkinWidgetDelegate()
		:m_pWidget(NULL)
		,m_bContinueModal(false)
	{
	}

	CBasicSkinWidgetDelegate::~CBasicSkinWidgetDelegate()
	{
	}

	void CBasicSkinWidgetDelegate::BsOnInitClientViewBeginCreateWnd( CBasicSkinRootView* pRootView )
	{
	}

	void CBasicSkinWidgetDelegate::BsOnInitClientViewAfterCreateWnd( CBasicSkinRootView* pRootView )
	{
	}

	const WNDCLASSEX* CBasicSkinWidgetDelegate::BsGetWidgetClass()
	{
		return NULL;
	}

	bool CBasicSkinWidgetDelegate::BsOnMessageFilter( HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam,LRESULT* lRet,CBasicSkinEvent* pEvent )
	{
		return false;
	}

	CBasicSkinView* CBasicSkinWidgetDelegate::BsGetDefFocusView()
	{
		return NULL;
	}

	void CBasicSkinWidgetDelegate::BeginEndRenderView( CBasicSkinCanvas* pCanvas,bool bBegin )
	{
	}

	void CBasicSkinWidgetDelegate::OnWidgetClose()
	{
	}

	bool CBasicSkinWidgetDelegate::OnWMCommond( CBasicSkinEvent* pEvent )
	{
		return false;
	}

	bool CBasicSkinWidgetDelegate::BsCanSetFocusWidget()
	{
		return true;
	}

	void CBasicSkinWidgetDelegate::UpdateScreenDC( HWND hWnd,HDC hdc,int x,int y,int cx,int cy,HDC hMem,int nAlpha,bool bLayer )
	{
		if(bLayer)
		{
			CBasicSkinWidget::MyUpdateLayerWindow(hWnd,hdc,x,y,cx,cy,hMem,nAlpha);
		}else
		{
			::BitBlt(hdc,0,0,cx,cy,hMem,0,0,SRCCOPY);
		}
	}

	HWND CBasicSkinWidgetDelegate::GetHwnd()
	{
		if(m_pWidget)
			return m_pWidget->m_hWnd;
		return NULL;
	}

	void CBasicSkinWidgetDelegate::SetWidget( CBasicSkinWidget* pWidget )
	{
		m_pWidget = pWidget;
	}

	CBasicSkinWidget* CBasicSkinWidgetDelegate::GetWidget()
	{
		return m_pWidget;
	}

	void CBasicSkinWidgetDelegate::DrawTitleBackground( CBasicSkinCanvas* pCanvas,LPRECT lpRect,const wchar_t* szTitle,int nDefH/*=30*/ )
	{
		if(!pCanvas)
			return;

		IBasicResourceMgr::Theme_DrawCurTitleBackground(pCanvas->m_pGraphics,lpRect,nDefH);
		COLORREF cl = IBasicResourceMgr::Theme_GetCurThemeTextColor();

		int cx = lpRect->right-lpRect->left-16;

		RECT rcDraw;
		rcDraw.left = lpRect->left+15;
		rcDraw.top = lpRect->top+13;
		rcDraw.right = lpRect->right-30;
		rcDraw.bottom = rcDraw.top+20;

		wstring str = szTitle ? szTitle : L"";

		pCanvas->DrawStringText(str.c_str(),&rcDraw,DT_LEFT|DT_VCENTER|DT_SINGLELINE,cl,14);

	}

	void CBasicSkinWidgetDelegate::CreateWindowRgn()
	{
		RECT rc;
		::GetClientRect(this->GetHwnd(),&rc);
		int cx = rc.right - rc.left;
		int cy = rc.bottom - rc.top;
		SIZE sz;
		sz.cx = cx;
		sz.cy = cy;

		HRGN hRgn = ::CreateRectRgn(0,0,cx,cy);

		POINT ptA[] = {{0,0},{0,1},{1,0},{2,0},{0,2}};

		for (int i=0;i<sizeof(ptA) / sizeof(ptA[0]);i++)
		{
			//Top Left
			HRGN hRgnTemp = ::CreateRectRgn(ptA[i].x,ptA[i].y,ptA[i].x+1,ptA[i].y+1);
			::CombineRgn(hRgn,hRgn,hRgnTemp,RGN_DIFF);
			::DeleteObject(hRgnTemp);
			//Top Right
			hRgnTemp = ::CreateRectRgn(sz.cx-1-ptA[i].x,ptA[i].y,sz.cx-ptA[i].x,ptA[i].y+1);
			::CombineRgn(hRgn,hRgn,hRgnTemp,RGN_DIFF);
			::DeleteObject(hRgnTemp);
			//Left Bottom
			hRgnTemp = ::CreateRectRgn(ptA[i].x,sz.cy - 1 -ptA[i].y,ptA[i].x+1,sz.cy - ptA[i].y);
			::CombineRgn(hRgn,hRgn,hRgnTemp,RGN_DIFF);
			::DeleteObject(hRgnTemp);
			//Right Bottom
			hRgnTemp = ::CreateRectRgn(sz.cx-1-ptA[i].x,sz.cy - 1 -ptA[i].y,sz.cx-ptA[i].x,sz.cy - ptA[i].y);
			::CombineRgn(hRgn,hRgn,hRgnTemp,RGN_DIFF);
			::DeleteObject(hRgnTemp);

		}

		::SetWindowRgn(this->GetHwnd(),hRgn,true);
	}

	void CBasicSkinWidgetDelegate::BsWidgetDoDoModal( HWND hParent )
	{
		m_bContinueModal = true;
		MSG msg;

		BOOL bEnable = FALSE;
		if (hParent)
		{
			bEnable = ::IsWindowEnabled(hParent);
			::EnableWindow(hParent,FALSE);
		}

		for(;;)
		{
			do
			{
				if (!::GetMessage(&msg,NULL,0,0))
				{
					::PostQuitMessage(0);
					goto ExitModal;
					break;
				}
				if (m_bContinueModal == false)
					goto ExitModal;

				//////////////////////////////////////////////////////////////////////////
				if(this->BsTranslateAccelerator(&msg))
					break;
				//////////////////////////////////////////////////////////////////////////
				//CaretBlinkTimer & MyHostWindow ? Direct Send To Window

				if (msg.message == 0x0118 && msg.wParam == IDSYS_CARET && ::GetWindowLongPtr(msg.hwnd,GWLP_USERDATA) != NULL)
				{
					DWORD dwExStyle = ::GetWindowLong(msg.hwnd,GWL_EXSTYLE);
					if (dwExStyle & WS_EX_LAYERED)
						::SendMessage(msg.hwnd,msg.message,msg.wParam,msg.lParam);
					else
					{
						TranslateMessage(&msg); 
						DispatchMessage(&msg); 
					}
				}
				else
				{
					TranslateMessage(&msg); 
					DispatchMessage(&msg); 
				}
			}while(::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE));
		}

ExitModal:
		if (hParent && ::IsWindow(hParent))
		{
			::EnableWindow(hParent,bEnable);
			::SetForegroundWindow(hParent);
		}
		if (m_pWidget->m_hWnd && ::IsWindow(m_pWidget->m_hWnd))
		{
			::DestroyWindow(m_pWidget->m_hWnd);
		}
	}

	void CBasicSkinWidgetDelegate::BsWidgetEndModal()
	{
		m_bContinueModal = false;
		::PostMessage(m_pWidget->m_hWnd,WM_NULL,0,0);
	}

	bool CBasicSkinWidgetDelegate::BsTranslateAccelerator(LPMSG lpMsg)
	{
		CBasicSkinWidget* pWidget = this->GetWidget();
		if( pWidget && (lpMsg->hwnd == pWidget->BsGetHwnd() || lpMsg->hwnd == pWidget->BsGetParent()))
		{
			return pWidget->BsTranslateAccelerator(lpMsg);
		}

		return false;
	}
}

